package cn.edu.nyist.integration.service.impl;

import cn.edu.nyist.integration.common.Const;
import cn.edu.nyist.integration.common.ServerResponse;
import cn.edu.nyist.integration.entity.Integration;
import cn.edu.nyist.integration.entity.LogInfo;
import cn.edu.nyist.integration.entity.User;
import cn.edu.nyist.integration.mapper.IntegrationMapper;
import cn.edu.nyist.integration.mapper.LogInfoMapper;
import cn.edu.nyist.integration.mapper.UserMapper;
import cn.edu.nyist.integration.service.UserService;
import cn.edu.nyist.integration.util.MD5Util;
import cn.edu.nyist.integration.util.PropertiesUtils;
import cn.edu.nyist.integration.util.RedisUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private LogInfoMapper logInfoMapper;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    @Transactional
    public ServerResponse<User> login(String username, String password) {

        //1.先判断用户名是否唯一
        int count = userMapper.selectByUsername(username);
        if (count == 0) {
            return ServerResponse.createByErrorMessage("用户名不存在");
        }
        //MD5加密+salt值
        password = password + PropertiesUtils.getProperty("password.salt");
        String md5 = DigestUtils.md5DigestAsHex(password.getBytes());

        //2.判断用户名是否和密码匹配
        User user = userMapper.selectLogin(username, md5);
        if (user == null) {
            return ServerResponse.createByErrorMessage("密码错误");
        }

        //3,判断用户的账号是不是被冻结
        int i = userMapper.checkStatus(username);
        if (i == 0) {
            //被冻结
            return ServerResponse.createByErrorMessage("您的账号被冻结请联系管理员解冻！");
        }

        //前端不需要密码,将密码值为空串
        user.setPassword(StringUtils.EMPTY);

        //登陆成功，将登录日志插入到表中
        LogInfo logInfo = this.assembleLogInfo(user);
        logInfoMapper.insert(logInfo);
        //修改登录时间
        userMapper.updateLoginTime();

        return ServerResponse.createBySuccessMessageData("登陆成功", user);
    }

    @Override
    public ServerResponse<String> register(User user) {

        //校验用户参数（username,email）
        //校验用户名
        ServerResponse<String> checkValid = this.checkValid(user.getUsername(), Const.USERNAME);
        if (!checkValid.isSuccess()) {
            return checkValid;
        }
        //校验email
        checkValid = this.checkValid(user.getEmail(), Const.EMAIL);
        if (!checkValid.isSuccess()) {
            return checkValid;
        }

        //需要对password进行加密
        //MD5加密+salt值
        String md5 = MD5Util.md5(user.getPassword());
        user.setPassword(md5);
        //设置创建时间
        user.setCreateTime(new Date());
        //设置默认头像
        user.setAvatar(PropertiesUtils.getProperty("user.avatar"));


        int rowCount = userMapper.insert(user);
        if (rowCount == 0) {
            return ServerResponse.createByErrorMessage("注册失败");
        }


        return ServerResponse.createBySuccessMessage("注册成功");
    }



    /**
     * 更新用户信息
     *
     * @param user
     * @return
     */
    @Override
    public ServerResponse<User> updateInformation(User user) {
        //1.username不能被更新
        //2.email 更新过后也是不能与他人重复的
        int rowCount = userMapper.checkEmailByUserId(user.getEmail(), user.getId());
        if (rowCount > 0) {
            return ServerResponse.createByErrorMessage("这个邮箱已经有人注册过了，请换一个邮箱再尝试");
        }

        user.setUpdateTime(new Date());
        //删除缓存
        redisUtil.del("user"+user.getId());

        int i = userMapper.updateByPrimaryKeySelective(user);
        if (i > 0) {
            return ServerResponse.createBySuccessMessageData("更新个人信息成功", user);
        }

        return ServerResponse.createByErrorMessage("更新个人信息失败");
    }


    public ServerResponse<String> checkValid(String str, String type) {
        if (StringUtils.isNotBlank(type)) {
            //isBlank方法判断传入的参数非空并且字符串长度不为0，还有字符串中不能含有空格
            //开始交验
            if (Const.USERNAME.equals(type)) {
                //校验用户名
                int i = userMapper.selectByUsername(str);
                if (i > 0) {
                    return ServerResponse.createByErrorMessage("用户名已存在！");
                }
            }
            //校验email
            if (Const.EMAIL.equals(type)) {
                int i = userMapper.checkEmail(str);
                if (i > 0) {
                    return ServerResponse.createByErrorMessage("email已存在！");
                }
            }

        } else {
            return ServerResponse.createByErrorMessage("参数错误");
        }
        return ServerResponse.createBySuccessMessage("校验成功");
    }

    // 封装LogInfo
    private LogInfo assembleLogInfo(User user) {
        LogInfo logInfo = new LogInfo();
        logInfo.setLoginTime(new Date());
        logInfo.setUsername(user.getUsername());
        logInfo.setStatus(0);
        logInfo.setMsg(Const.LOGIN_SUCCESS);
        return logInfo;
    }

    /**
     * 查找用户
     *
     * @param id
     * @return
     */
    @Override
    public ServerResponse<User> selectById(String id) {
        //首先从redis中查询是否含有user，如果有直接返回
        User redisUser = (User) redisUtil.get("user"+id);
        if (redisUser!=null){
            return ServerResponse.createBySuccessData(redisUser);
        }
        //没的话查数据库
        User user = userMapper.selectByPrimaryKey(id);

        if (user == null) {
            return ServerResponse.createByErrorMessage("用户不存在！");
        }

        //给redis中添加user
        redisUtil.set("user"+id,user);

        return ServerResponse.createBySuccessData(user);
    }

    @Override
    public ServerResponse<User> checkAnswer(String question, String answer, String id) {
        User user = userMapper.selectByQuestionAndAnswer(question, answer, id);
        if (user == null) {
            return ServerResponse.createByErrorMessage("密保问题回答错误!");
        }
        return ServerResponse.createBySuccessData(user);
    }

    /**
     * 重置密码
     *
     * @param passwordOld
     * @param passwordNew
     * @param user
     * @return
     */
    @Override
    public ServerResponse<String> resetPassword(String passwordOld, String passwordNew, User user) {
        //为防止横向越权，我们需要校验旧的密码一定是这个用户的
        int rowCount = userMapper.checkPassword(MD5Util.md5(passwordOld), user.getId());
        if (rowCount == 0) {
            //旧密码错误
            return ServerResponse.createByErrorMessage("旧密码错误");
        }
        user.setPassword(MD5Util.md5(passwordNew));
        System.out.println("重置密码中的user"+user);
        //修改密码之前需要清空缓存中的当前用户
        redisUtil.del("user"+user.getId());
        int updateCount = userMapper.updateByPrimaryKeySelective(user);
        if (updateCount > 0) {
            //修改成功
            return ServerResponse.createBySuccessMessage("修改密码成功");
        }
        return ServerResponse.createByErrorMessage("修改密码失败");
    }


    @Override
    public PageInfo<LogInfo> selectAllLogInfo(int pageNum, int pageSize, String username) {
        PageHelper.startPage(pageNum, pageSize);
        List<LogInfo> logInfos = logInfoMapper.selectAll(username);
        PageInfo<LogInfo> pageInfo = new PageInfo(logInfos);

        pageInfo.setList(logInfos);
        return pageInfo;
    }

    @Override
    public PageInfo<User> selectUsers(int pageNum, int pageSize, String username, Integer role) {
        if (username != null) {
            username = "%" + username + "%";
        }
        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userMapper.selectAll(username, role);
        PageInfo<User> pageInfo = new PageInfo<>(users);
        pageInfo.setList(users);
        return pageInfo;
    }

    @Override
    public ServerResponse delUserById(Long id) {
        if (id == null) {
            return ServerResponse.createByErrorMessage(Const.ILLEGAL_ARGUMENT);
        }
        //删除之前先清除缓存
        redisUtil.del("user"+id);

        int rowCount = userMapper.deleteByPrimaryKey(id.toString());
        if (rowCount < 1) {
            return ServerResponse.createByErrorMessage("删除用户失败");
        }
        return ServerResponse.createBySuccess();
    }


    /**
     * 更新用户状态（停用/解冻）
     *
     * @param username
     * @param phone
     * @param status
     * @return
     */
    @Override
    public ServerResponse updateStatus(String username, String phone, Integer status) {

        //更新用户前需要将redis缓存清空
        String id = userMapper.selectIdByUsername(username);

        redisUtil.del("user"+id);

        int rowCount = userMapper.updateByUsername(username, phone, status);
        if (rowCount == 0) {
            return ServerResponse.createByErrorMessage("更新信息失败");
        }
        return ServerResponse.createBySuccess();
    }

}
